package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.dao.TInterfaceDao;
import com.ruoyi.system.domain.dto.TInterfaceDto;
import com.ruoyi.system.domain.po.*;
import com.ruoyi.system.domain.vo.TInterfaceCategoryVo;
import com.ruoyi.system.domain.vo.TInterfaceVo;
import com.ruoyi.system.mapper.TInterfaceCategoryMapper;
import com.ruoyi.system.mapper.TInterfaceLogMapper;
import com.ruoyi.system.mapper.TInterfaceMapper;
import com.ruoyi.system.service.TInterfaceService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author nanyang
 */
@Service
public class TInterfaceServiceImpl implements TInterfaceService {

    @Resource
    private TInterfaceMapper interfaceMapper;

    @Resource
    private TInterfaceCategoryMapper categoryMapper;

    @Resource
    private TInterfaceDao interfaceDao;

    @Resource
    private TInterfaceLogMapper interfaceLogMapper;

    @Override
    public Integer insertInterface(TInterfaceDto.Insert interfaceInsert) {
        // 新增实体数据
        TInterface tInterface = BeanUtil.copyProperties(interfaceInsert, TInterface.class);
        tInterface.setId(IdUtil.getSnowflake().nextId());
        tInterface.setCreateBy(SecurityUtils.getUsername());
        tInterface.setCreateTime(new Date());
        tInterface.setMethod((byte)interfaceInsert.getMethod().getCode());
        return interfaceMapper.insertSelective(tInterface);
    }

    @Override
    public Integer updateInterface(TInterfaceDto.Update interfaceUpdate) {
        // 修改实体
        TInterface tInterface = BeanUtil.copyProperties(interfaceUpdate, TInterface.class);
        tInterface.setUpdateBy(SecurityUtils.getUsername());
        tInterface.setUpdateTime(new Date());
        return interfaceMapper.updateByPrimaryKeySelective(tInterface);
    }

    @Override
    public Integer deleteInterface(TInterfaceDto.Delete interfaceDelete) {
        TInterfaceExample interfaceExample = new TInterfaceExample();
        interfaceExample.createCriteria().andIdIn(interfaceDelete.getIdList());
        TInterface tInterface = new TInterface();
        tInterface.setDelFlag((byte) 2);
        return interfaceMapper.updateByExampleSelective(tInterface, interfaceExample);
    }

    @Override
    public List<TInterfaceVo.Result> listInterface(TInterfaceDto.Query queryInterface) {
//        TInterfaceExample interfaceExample = new TInterfaceExample();
//        TInterfaceExample.Criteria criteria = interfaceExample.createCriteria().andDelFlagEqualTo((byte)0);
//        if (StrUtil.isNotEmpty(queryInterface.getCode())) {
//            criteria.andCodeEqualTo(queryInterface.getCode());
//        }
//        if (StrUtil.isNotEmpty(queryInterface.getName())) {
//            criteria.andNameLike("%" + queryInterface.getName() + "%");
//        }
//        if (queryInterface.getCategoryId() != null) {
//            criteria.andCategoryIdEqualTo(queryInterface.getCategoryId());
//        }
//        if (queryInterface.getMethod() != null) {
//            criteria.andMethodEqualTo(queryInterface.getMethod());
//        }
//        if (StrUtil.isNotEmpty(queryInterface.getUri())) {
//            criteria.andUriLike("%" + queryInterface.getUri() + "%");
//        }
//        interfaceExample.setOrderByClause("create_time desc");
        return interfaceDao.queryInterface(queryInterface.getCategoryId(),queryInterface.getName(), queryInterface.getUri(), queryInterface.getMethod(), queryInterface.getCode());
    }

    @Override
    public Integer insertCategory(TInterfaceDto.CategoryInsert categoryInsert) {
        // 检验父级id是否存在，不存在，则默认为0
        TInterfaceCategory parentCategory = categoryMapper.selectByPrimaryKey(categoryInsert.getParentId());
        // 新增实体数据
        TInterfaceCategory interfaceCategory = BeanUtil.copyProperties(categoryInsert, TInterfaceCategory.class);
        interfaceCategory.setId(IdUtil.getSnowflake().nextId());
        interfaceCategory.setCreateBy(SecurityUtils.getUsername());
        interfaceCategory.setCreateTime(new Date());
        String parentAncestor = StringUtils.isNotNull(parentCategory) ? parentCategory.getAncestors() + "," : "";
        if (categoryInsert.getParentId() == null) {
            categoryInsert.setParentId(0L);
        }
        interfaceCategory.setAncestors(parentAncestor + categoryInsert.getParentId());
        return categoryMapper.insertSelective(interfaceCategory);
    }

    @Override
    public Integer updateCategory(TInterfaceDto.CategoryUpdate categoryUpdate) {
        // 修改实体
        TInterfaceCategory interfaceCategory = BeanUtil.copyProperties(categoryUpdate, TInterfaceCategory.class);
        interfaceCategory.setUpdateBy(SecurityUtils.getUsername());
        interfaceCategory.setUpdateTime(new Date());
        // 根据部门表修改逻辑，做父子级修改
        TInterfaceCategory parentCategory = categoryMapper.selectByPrimaryKey(categoryUpdate.getParentId());
        TInterfaceCategory oldCategory = categoryMapper.selectByPrimaryKey(categoryUpdate.getId());
        if (StringUtils.isNotNull(parentCategory) && StringUtils.isNotNull(oldCategory)) {
            String newAncestors = parentCategory.getAncestors() + "," + parentCategory.getId();
            String oldAncestors = oldCategory.getAncestors();
            interfaceCategory.setAncestors(newAncestors);
            updateCategoryChildren(interfaceCategory.getId(), newAncestors, oldAncestors);
        }
        return categoryMapper.updateByPrimaryKeySelective(interfaceCategory);
    }

    /**
     * 级联修改
     * @param id            当前id
     * @param newAncestors  新的父级的祖级列表
     * @param oldAncestors  旧的父级的祖级列表
     */
    private void updateCategoryChildren(Long id, String newAncestors, String oldAncestors) {
        List<TInterfaceCategory> children = interfaceDao.selectByCategoryChildren(id);
        for (TInterfaceCategory child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (!children.isEmpty()) {
            interfaceDao.updateCategoryChildren(children);
        }
    }

    @Override
    public Integer deleteCategory(TInterfaceDto.CategoryDelete categoryDelete) {
        TInterfaceCategoryExample categoryExample = new TInterfaceCategoryExample();
        categoryExample.createCriteria().andIdIn(categoryDelete.getIdList());
        TInterfaceCategory category = new TInterfaceCategory();
        category.setDelFlag((byte) 2);
        return categoryMapper.updateByExampleSelective(category, categoryExample);
    }

    @Override
    public List<TInterfaceCategoryVo.Result> listCategory(TInterfaceDto.QueryCategory queryCategory) {
        TInterfaceCategoryExample categoryExample = new TInterfaceCategoryExample();
        TInterfaceCategoryExample.Criteria criteria = categoryExample.createCriteria().andDelFlagEqualTo((byte)0);
        if (StrUtil.isNotEmpty(queryCategory.getName())) {
            criteria.andNameLike("%" + queryCategory.getName() + "%");
        }
        categoryExample.setOrderByClause("order_num asc, create_time desc");
        List<TInterfaceCategory> categoryList = categoryMapper.selectByExample(categoryExample);
        return categoryList.stream().map(e -> BeanUtil.copyProperties(e, TInterfaceCategoryVo.Result.class)).collect(Collectors.toList());
    }

    @Override
    public List<TInterfaceCategoryVo> treeCategory(TInterfaceDto.TreeCategory treeCategory) {
        // 查询所有数据
        TInterfaceCategoryExample categoryExample = new TInterfaceCategoryExample();
        categoryExample.createCriteria().andDelFlagEqualTo((byte) 0);
        List<TInterfaceCategory> categoryList = categoryMapper.selectByExample(categoryExample);
        // 拷贝数据到vo
        List<TInterfaceCategoryVo> categoryVoList = categoryList.stream().map(e -> BeanUtil.copyProperties(e, TInterfaceCategoryVo.class)).collect(Collectors.toList());
        return categoryVoList.stream()
                .filter(o -> {
                    if(treeCategory.getId() == null || treeCategory.getId() == 0L) {return Objects.equals(0L, o.getParentId());}
                    else { return Objects.equals(treeCategory.getId(), o.getId());}
                })
                .peek(o -> o.setChildren(getChildList(o, categoryVoList)))
                .collect(Collectors.toList());
    }


    @Override
    public List<TInterfaceLog> queryLog(TInterfaceDto.LogQuery logQuery) {
        TInterfaceLogExample logExample = new TInterfaceLogExample();
        TInterfaceLogExample.Criteria criteria = logExample.createCriteria().andDelFlagEqualTo((byte) 0);
        if (StrUtil.isNotEmpty(logQuery.getAppId())) {
            criteria.andAppIdEqualTo(logQuery.getAppId());
        }
        if (StrUtil.isNotEmpty(logQuery.getName())) {
            criteria.andAppIdLike("%" + logQuery.getAppId() + "%");
        }
        if (logQuery.getStatus() != null) {
            criteria.andStatusEqualTo(logQuery.getStatus());
        }
        if (logQuery.getStartTime() != null) {
            criteria.andTimeGreaterThanOrEqualTo(logQuery.getStartTime());
        }
        if (logQuery.getEndTime() != null) {
            criteria.andTimeLessThanOrEqualTo(logQuery.getEndTime());
        }
        return interfaceLogMapper.selectByExample(logExample);
    }

    @Override
    public void importData(List<TInterfaceDto.Export> resultList, boolean updateSupport) {
        for (TInterfaceDto.Export result : resultList) {
            insertExportInterface(result);
        }
    }

    public Integer insertExportInterface(TInterfaceDto.Export interfaceInsert) {
        if (StrUtil.isEmpty(interfaceInsert.getUri())) {
            throw new BaseException("");
        }
        // 新增实体数据
        String categoryName = interfaceInsert.getCategoryName();
        if (StrUtil.isNotEmpty(categoryName)) {
            TInterfaceCategoryExample tInterfaceCategoryExample = new TInterfaceCategoryExample();
            tInterfaceCategoryExample.createCriteria().andDelFlagEqualTo((byte) 0).andNameEqualTo(categoryName);
            List<TInterfaceCategory> tInterfaceCategories = categoryMapper.selectByExample(tInterfaceCategoryExample);
            if (CollectionUtil.isNotEmpty(tInterfaceCategories)) {
                interfaceInsert.setCategoryId(tInterfaceCategories.get(0).getId());
            }
        }
        TInterface tInterface = BeanUtil.copyProperties(interfaceInsert, TInterface.class);
        tInterface.setId(IdUtil.getSnowflake().nextId());
        tInterface.setCreateBy(SecurityUtils.getUsername());
        tInterface.setCreateTime(new Date());
        if (interfaceInsert.getMethodString() != null) {
            //  GET(1, "get"),
            //    POST(2, "post"),
            //    PUT(3, "put"),
            //    DELETE(4, "delete"),
            //    PATCH(5, "patch");
            if ("GET".equals(interfaceInsert.getMethodString())) {
                tInterface.setMethod((byte) 1);
            }
            if ("POST".equals(interfaceInsert.getMethodString())) {
                tInterface.setMethod((byte) 2);
            }
            if ("PUT".equals(interfaceInsert.getMethodString())) {
                tInterface.setMethod((byte) 3);
            }
            if ("DELETE".equals(interfaceInsert.getMethodString())) {
                tInterface.setMethod((byte) 4);
            }
            if ("PATCH".equals(interfaceInsert.getMethodString())) {
                tInterface.setMethod((byte) 5);
            }
        }

        return interfaceMapper.insertSelective(tInterface);
    }

    /**
     * stream组树
     * @param categoryVo
     * @param list
     * @return
     */
    private List<TInterfaceCategoryVo> getChildList(TInterfaceCategoryVo categoryVo, List<TInterfaceCategoryVo> list) {
        return list.stream()
                //筛选出父节点id == parentId 的所有对象 => list
                .filter(o -> Objects.equals(categoryVo.getId(), o.getParentId()))
                .peek(o -> o.setChildren(getChildList(o, list)))
                .collect(Collectors.toList());
    }
}
